Skip to main content
Glama

CJ-MCP

by PoivronMax
增量引擎串讲.md8.54 kB
# 增量引擎串讲 ## 目录 1. [增量引擎](#增量引擎) - [什么是增量引擎/增量更新](#-什么是增量引擎增量更新) - [核心概念](#-核心概念) - [增量更新概要流程图](#-增量更新概要流程图) 2. [基于增量引擎的UI Demo](#基于增量引擎的ui-demo) - [UI demo](#ui-demo) - [创建流程](#创建流程) - [更新流程](#更新流程) --- ## 增量引擎 ### - 什么是增量引擎/增量更新 增量引擎可以理解为: 在 UI/树形结构的重建过程中,精准追踪“哪里改变了”,只重算和重建“受影响”的局部,而不是整棵树全量重建。目标是把每一帧的更新成本由全量降为“受影响子集” **插入wiki中图片** ### - 核心概念 - Scope(记忆化作用域) **待加入原wiki中的补充** - 由 `getMemoScope` 在某个父作用域下按调用点哈希 `id` 创建/复用。 - 保存上次计算值、子作用域与挂接的 `IncrementalNode`,并跟踪依赖。 - 关键字段/行为:`recomputeNeeded`、`isUnchanged()`、`recache(newValue)`、`invalidate()`。 - State(可变状态) - 抽象类 `AbstractState` 及实现 `StateImpl`;亦包含参数状态 `ParameterImpl`(函数形参被包成 State 以可追踪)。 - 读时登记依赖,写时置 `updateNeeded = true` 并在快照阶段比较 `snapshot` 与 `current` 判定 `modified`。 - Dependency(依赖追踪) - 在作用域/状态被“读取”时,通过 `manager.getDependency()` 注册到 `Dependencies`,用于之后精准失效/增量重算。 - IncrementalNode(增量节点) - 双向链 + `incrementalRef` 指针。提供 `incrementalUpdateSkip(count)` 快速跳过未变更子树;在 `incrementalUpdateDone(parent)` 中完成插入/连接与一致性校验。 - Manager(状态管理器) - `StateManagerImpl` 是运行时核心:持有 `currentScope`、`createdStates`、`dirtyScopes`、`updateNeeded` 等;提供根装配 `updatableNode`、快照推进 `updateSnapshot()`、以及作用域构造 `getMemoScope(...)`。 ### - 增量更新概要流程图(参考“详解.md”的讲解方式) ```text 外部触发(创建为例) └─ memoRoot/updatableNode 建立根 Scope+Node(冻结) └─ 执行 update(被 Memo/MemoIntrinsic 注入) ├─ manager.getMemoScope 获取/创建子 Scope ├─ scope.param 包装形参为 State(登记依赖) ├─ scope.isUnchanged? │ ├─ 是 → scope.getCached(登记依赖,节点跳过) │ └─ 否 → 计算 compute → scope.recache(更新缓存、断开失效子树、节点增量接入) └─ 返回 状态改变(State.setValue) └─ 标记 manager.updateNeeded = true └─ 外部驱动 updateSnapshot() //下一帧,触发更新 ├─ 遍历 createdStates:updateStateSnapshot 判定 modified ├─ 作用域 invalidate 冒泡到顶层,加入 dirtyScopes └─ 消费 dirtyScopes:scope.isModified() → 必要时 getValue()/recache(仅受影响子树重算) ``` ## 基于增量引擎的UI Demo ### UI demo ``` code here ``` ### 创建流程 ``` memoRoot(rootNode, update) ├─ GlobalStateManager.instance() → 返回 manager ├─ 创建 lambda1: { => manager.runWithFrozen(update) } └─ updatableNode(rootNode, lambda1, None) ├─ 创建 lambda2: { => update(); node } ├─ 创建 lambda3: {_ => cleanup?()} ├─ ScopeImpl.init(None, 2, lambda2, lambda3, None) │ ├─ super(None, 2) │ ├─ this.myCompute = lambda2 [保存,不执行] │ └─ this.myCleanup = lambda3 [保存,不执行] ├─ scope.param(0, lambda4, ...) [lambda4 保存,不执行] ├─ scope.param(1, lambda5, ...) [lambda5 保存,不执行] └─ 返回 scope [根作用域创建完成] ``` ![create](https://img.plantuml.biz/plantuml/png/jLPDQzH06BxdLmpraeLjS3V9PRMrAhIA_P0MyM15ficq6qmc8Pa8LGIzQ0lrreFGLXGFYY281wjMwPzfjhtv5voFVCniDsmGF2oPsNtU9yyyppipEvCG69CqyBM8FZt7Yo0cOE9qz-DWw_3awFtfs-SJ02RWJe9Y5HAW85mEGy9_NiWdAcJE3zUWlq8WGGiGmmqKS_3SoeAAan4tWyWNb6Ak8jF8XGIk-MWnT94GLdmpHEc44M9SgrYFgJ0-R_6AvMAgLlWmM7DXXqFcE-32lBVH9zVyT2IiAs3TCJ1JmCmnC4l0h34mMy1i6QQnOC3aT9b03nJ1y7Kpdzg0suPQ6dI8zuYEghoqOiGuQ30zu67Q4jX1kWHdYT4Fc5HUT7Qyc-sz0K4Ub8iKl8P3EegPKX2kIsNPrbvsz1FaVg_Y9s1gkY0nuXJVzKX_DWuV8wpdki5JHMOTLQLNpKyIDjzHLrnsJmyehQLZxbjEt0QB8PRjgvfEAuTScLX53pXzv3oS3MFUsTV384g9XpTaIulspf_SMadDqYrPTW4UybJ2AqvqSrE5VNhh4c3BeIugOckh9H-xTJvscsengPO7J8pZ8uZJw8hUQgZ3b7IOTJhCeGJApTq3vH5WUDWZEekm3Rf5gEN0F9TkTK1evN28EqaZ51UKhLeOwNk94MoA1a1WgihdtidnGVRvzPzVEoVVNmssFvozsxa_baOuMDAODJGoZ-fllcCJlZZ9Hcd5TMxo6YFVfbG2qpG6p9hkAY6GRWQNLh1fWufbj5w06xQOHLkCDfYR1j4D3yKmTlgRI-iwfspQR9RKR5PTirdrzj3Z6WRwnQAfh3Om36DaJwbhaYZoIY0YpRQ-WDkC515nARAmHxRAo8ZvmLCJSJDNxT6kic2QccfBfjfrfjhZJEqKfjh_RAhz_qsLrZ3gaZotvQGhfBgGs5iJTd_aLUBWO2Z-wiliQffMBeRo7kSEX8_etcGCRSc2mVQpmVvsxWJ83h-AZB8Vtwh3u_UBxE3bOF-JS4ARGTXb_mcrlm00) ### 更新流程 ``` 执行rootScope.getValue() ├─ ScopeImpl.getValue() │ ├─ isUnchanged() │ │ ├─ isRecomputeNeeded() → true │ │ ├─ this.scopeInternal = manager.currentScope [保存] │ │ ├─ manager.currentScope = this [切换] │ │ └─ 返回 false │ ├─ compute = this.myCompute.getOrThrow() [获取 lambda2] │ └─ recache(compute()) [执行 lambda2] │ ├─ 执行 lambda2: { => update(); node } │ │ └─ 执行 update() [即 lambda1] │ │ ├─ frozen = true │ │ ├─ 执行 runnable(this) [即用户 update] │ │ │ └─ NodeAttach(createA, updateA) │ │ │ ├─ getMemoScope(...) [创建子作用域] │ │ │ ├─ createA() → 创建 nodeA [执行 create lambda] │ │ │ ├─ updateA(nodeA) [执行 update lambda] │ │ │ │ └─ counter.getValue() │ │ │ │ └─ counter.onAccess() [登记依赖] │ │ │ └─ recache(nodeA) │ │ └─ frozen = old │ │ └─ 返回 node │ ├─ manager.currentScope = this.scopeInternal [恢复] │ ├─ this.myValue = node │ ├─ this.recomputeNeeded = false │ ├─ detachChildScopes(None) │ ├─ parent?.increment(...) │ ├─ nodeAttached?.incrementalUpdateDone(...) │ └─ getCached() │ └─ 返回 node └─ 返回 node ``` ![update](https://img.plantuml.biz/plantuml/png/hLXRRnj557xVNx4gBskfMBKVZTBM684Yt1QL1eH87hQx4tkbzQorksuLAgH4I2H52LHAb1OblH0Gy18hAfS8d3H_nhjsdlWBp7rdrhDsKtZopEpvpdtEEUFhKMo7SQ_Z6rtqwpbUruQnUMcqyskwSJmS_3XwiNR9j2Dp8GAXIlAn4tJ1VAVhBq8h38AOx4k4-3RVvX2n7OCRDhHR8CH0GilsAgLlT-wwTfKGDAlcMqslrOxVzNj0HrQXP9L2ih07F_NYzljXy0M0X9WkTIQRlQwBj1GsBv0jO_qPyFtWlWgx6RYW7iUsqoQORAkIjK1y0tG2uXL2-07GkaXoQeJNTUfHSbvNQPqG8DNgv7k3hbM2UOX8EW36je_LolHJoQZ5b0yrDoyewC4OX4Wb4a6gKOCUgfGVsQ7T0R4KNd9Y6DYLvjjNiyoecSWZdzWeLbR9i9tOkuVTd2ME8POvc1SjGATjmnPmBuoy3PoWq-t5u2O0RX5UWgluyTbEilVCZ4EKNowuYEIuxKLbBuk6EOVY0C5qUeWYHPoCgA_aUBDBWtJwzZZvRjVii4iabEAtYlqMcC9XaZKSE5qtafhpEFwGMCCObPrU628B2UaY_7nuzZGvV9ASRYSFjuQd--Y69S-VBnMOekE1M6DvY5MoiPvk7KXCNjVKMn_ECa_hccNRZx09v_khuv_NpjUtHlt7InSCEqisPaIvizAW1sMK-hV2E-qmk6-La0mMH5RqbeePXi11XGLOZB5LmkZquI_Z7pOpj4v36A1zY4kO6IpB75Nm8dnWpbrb9T0glMFY73I_LFLfLf6JZhv2SJ257fbGjLeRQ8iX5G7Xl758jtvZWYkIrceTDz0MCQ3rEiiHfQ9RbAUa12ll1lsL6IpJapbwYrMtS9fn_zNej9zyFHWDjjCNwydPuqLu_kHbUdWm-kRFT7LjUDPFT_wIkMUD0iMe1w5zrmSMZZapKsajagr53SQGFY3sMK-fIMkBrV_BZ6zTSe3KXOniZNdnjaFgh-X8LhbSbk2YD_45Hj8ML3EJZRray7To-4XSnWp8sXJz8JShaySk5YaTyaLYc4nKpk8Yd50o5qOPozARUeebMyuXh7FM655TJcRULTclY0LtWfdhiBa0K4d48265MGF9TyaQ2X22z3wOG745SpRnK16VaKP2lm4NPJvbCYLaic2rUZBQsGwd6QbtE1inQZnjBQAGv7K-WnXiGQ94fmrSKycYh9iU-4XYi8K2363TSK0KwG0IVRwpkg0Be0kWipAzumWvB5JCLPhMerDEIF50L0v1oulGiKLvu1eo-dumxXyDNpqT_x6xb77Go6NTqqnMJvH4cN2D70c6lQ95Y2ZaKYFfRwORZsI829m-6tdtoiSxbu4P8DtxFTqz6friuo42sJD94Qe37SfkqhUBihde6l6yblNEbVL9Q-KQAzThgTjeN2G8ftQdm7V5PzO_9tdnBeTR9ElBaqJDYcZ2LSK1v5Gx-f2lCelgj05YxI3vAHlkBZxRgRFa_pZMJKwjdHLICbWDd4NBXZMN3mjJoOiIiGZa0fmuZRRdk-Gail23e5H8ZrvPo6_NiaS4xTX5v7B9loQ_F6ZklOTaKGQ5751zRH3up4VIczVCoTIJa9he5ZjJLpsdEaY1192wPJg4F_-aJ586-PbFYlozqhyW_XiKrvVNGP7x7Dn3WS28ovB49kdPh97JUlBFoQQuuCdnIrgGyN3yRD-uZjo8_pqoZ7y1)

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PoivronMax/idlize-cj-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server